package cn.wolfcode.job;

import cn.wolfcode.common.web.Result;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.feign.SeckillProductFeignApi;
import cn.wolfcode.redis.JobRedisKey;
import com.alibaba.fastjson.JSON;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 定时任务, 将要秒杀的商品在特定时间传给前端
 */
@Component
@Setter
@Getter
@Slf4j
public class MyInitSeckillProductJob implements SimpleJob {
    // 配置中为 每4秒一次
    @Value("${jobCron.myInitSeckillProductJob}")
    private String cron;

    @Autowired
    private SeckillProductFeignApi seckillProductFeignApi;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public void execute(ShardingContext shardingContext) {
//        System.out.println(shardingContext.getShardingParameter());
        log.info("开始执行那个......初始化那啥的定时任务");
        dowork(shardingContext.getShardingParameter());

        log.info("结束执行那个......初始化那啥的定时任务");
    }

    /**
     * 1. 数据分散在两个数据库的表中, 因此不能直接join, 要分别查询数据库后聚合
     * 2. 将库存提前放入redis, 以限制多余库存的请求, 降低mysql访问量
     * @param time
     */
    private void dowork(String time) {
        // 1. 远程调用 秒杀服务 获取 productVO
        Result<List<SeckillProductVo>> listResult = seckillProductFeignApi.selectByTime(Integer.parseInt(time));

        // listResult == null , 秒杀服务崩了, 走的降级; 状态码不是200, 服务内部报错;
        if (listResult != null || !listResult.hasError()) {
            List<SeckillProductVo> vos = listResult.getData();
            if (vos != null || vos.size() > 0){
                for (SeckillProductVo vo : vos) {
                    // 2. 将 productVO 放到 redis 中        seckillProductList:  time            key=秒杀商品ID, value=json(productVO)
                    HashOperations<String, Object, Object> stringObjectObjectHashOperations = redisTemplate.opsForHash();
                    stringObjectObjectHashOperations.put(JobRedisKey.SECKILL_PRODUCT_LIST.getRealKey(time), String.valueOf(vo.getId()), JSON.toJSONString(vo));

                    // 3. 将库存数量提前放入 redis 中         seckillStockCount:  time            key=秒杀商品ID, value=库存数量
                    stringObjectObjectHashOperations.put(JobRedisKey.SECKILL_STOCK_COUNT_HASH.getRealKey(time), String.valueOf(vo.getId()), String.valueOf(vo.getStockCount()));
                }
            }
        }
    }
}
